package com.ztc.service;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.TextAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSimpleField;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import com.ztc.bean.ExcelModel;
import com.ztc.bean.ProjectModel;
import com.ztc.bean.QuoteModel;
import com.ztc.bean.ReportHistoryModel;
import com.ztc.bean.ReportModel;
import com.ztc.costants.Constants;
import com.ztc.dao.ProjectDao;
import com.ztc.dao.ReportDao;
import com.ztc.dao.ReportHistoryDao;
import com.ztc.util.DateUtil;
import com.ztc.util.EasyUITreeUtil;
import com.ztc.util.ExcelQuoteUtil;
import com.ztc.util.HtmlToWordUtil;
import com.ztc.util.MoneyNumberUtil;
import com.ztc.util.NumberFormatUtil;
import com.ztc.util.NumberUtil;
import com.ztc.util.RegexUtils;
import com.ztc.util.ValidateUtil;

@Service
public class ReportService {
	
	@Autowired
	private ReportDao reportDao;
	
	@Autowired
	private ReportHistoryDao reportHistoryDao;
	
	@Autowired
	private ProjectDao projectDao;

	private static final String[] methodNameArr = new String[]{"资产基础法", "收益法", "市场法"};
	
	private static final String[] notShowTitle = new String[]{"封面", "明细表封面", "委托人信息", "企业关于进行资产评估有关事项的说明", "委托人签章页", "被评估单位签章页", "正文", "选择价值类型的理由分析", "价值类型定义"};
	
	private List<String> notShowTitleList = Arrays.asList(notShowTitle);

	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");

	private static NumberFormatUtil nf = new NumberFormatUtil("#,##0.00"); //保留两位小数
	
	private String[] breakSign = new String[]{"、","，", "；", "。"};
	
	private List<BigInteger> numIdArr = new ArrayList<BigInteger>();
	
	private List<String> warningMsgList = new ArrayList<String>(); //替换错误提示信息
	
	private List<String> errorMessageList = new ArrayList<String>();

	public static void main(String[] args) {
		ReportService obj = new ReportService();
		obj.testRest();
	}

	public void testRest() {
		RestTemplate restTemplate = new RestTemplate();
		Map<String, Object> requestObj = new HashMap<String, Object>();
		requestObj.put("authType", Constants.AuthType_Report);
		Object res = restTemplate.postForObject(
				"http://192.168.10.41:1008/queryAuthorityTree", requestObj, Object.class);
		System.out.println(res);
	}
	
	/**
	 * 查询报告内容
	 * @param authId
	 * @param relation
	 * @param projectId
	 * @throws Exception 
	 */
	public ReportModel queryReportContent(int authId, String relation, int projectId) throws Exception {
		ReportModel report = reportDao.queryReportContent(authId, relation, projectId);
		ProjectModel project = queryProjectById(projectId);
		String newTemplate = dealQuoteRule(project, authId, report.getTemplate(), 1);
		report.setTemplate(newTemplate);
		String newContent = dealQuoteRule(project, authId, report.getContent(), 1);
		report.setContent(newContent);
		return report;
	}
	
	/**
	 * 
	 * @param relation
	 * @param projectId
	 * @param version
	 * @return
	 */
	public ReportHistoryModel queryVersionContent(String relation, int projectId, String version) {
		return reportHistoryDao.queryReportHistory(relation, projectId, version);
	}
	
	/**
	 * 查询报告模板
	 * @param authId
	 * @param projectId
	 * @return
	 * @throws Exception
	 */
	public ReportModel queryReportTemplate(int authId, int projectId) throws Exception {
		ReportModel report = reportDao.queryReportTemplate(authId);
		ProjectModel project = queryProjectById(projectId);
		String newTemplate = dealQuoteRule(project, authId, report.getTemplate(), 1);
		report.setTemplate(newTemplate);
		return report;
	}
	
	/**
	 * 保存报告内容
	 * @param reportModel
	 */
	@Transactional
	public ReportModel saveReportContent(ReportModel reportModel) {
		reportModel.setPureContent(removeAllHtmlTag(reportModel.getContent()));
		
		if(reportModel.getContentId() == null) { //新增
			//判断是否已进入审批，如果进入，生成版本号
			Map<String, Object> map = reportHistoryDao.queryApprovalInfo(reportModel.getProjectId());
			if(map != null && !map.isEmpty()) {
				int num = Integer.parseInt(map.get("num") + "");
				if(num > 0) {
					reportModel.setVersion("v1.0");
				}
			}
			reportDao.addReportContent(reportModel);
		} else { //修改
			ReportModel old = reportDao.queryReportContentByCon(reportModel);
			if(old == null) {
				throw new IllegalArgumentException("信息已过期，请刷新后重试");
			}
			if((StringUtils.isBlank(old.getContent()) || !old.getContent().equals(reportModel.getContent())) && StringUtils.isNotBlank(old.getVersion())) {
				//获取审批版本
				Map<String, Object> approvalMap = reportHistoryDao.queryApprovalVersion(reportModel.getProjectId());
				String approvalVersion = "v1.0";
				if(approvalMap != null) {
					approvalVersion = approvalMap.get("version") + "";
				}
				ReportHistoryModel reportHistory = new ReportHistoryModel();
				reportHistory.setProjectId(reportModel.getProjectId());
				reportHistory.setApprovalVersion(approvalVersion);
				reportHistory.setContent(old.getContent());
				reportHistory.setEnterpriseId(old.getEnterpriseId());
				reportHistory.setTableId(reportModel.getRelation());
				reportHistory.setVersion(old.getVersion());
				reportHistoryDao.addReportHistory(reportHistory);
				//获取新的版本号
				String newVersion = getNewVersion(old.getVersion());
				reportModel.setVersion(newVersion);
			}
			reportDao.updateReportContent(reportModel);
		}
		ReportModel model = new ReportModel();
		model.setRelation(reportModel.getRelation());
		model.setProjectId(reportModel.getProjectId());
		return reportDao.queryReportContentByCon(model);
	}
	
	/**
	 * 查询历史版本列表
	 * @param relation
	 * @param projectId
	 * @return
	 */
	public List<String> queryHistoryList(String relation, int projectId) {
		List<ReportHistoryModel> reportHistoryList = this.reportHistoryDao.queryHistoryList(relation, projectId);
		List<String> versionList = new ArrayList<String>();
		if(reportHistoryList != null && reportHistoryList.size() > 0) {
			for(ReportHistoryModel reportHistory : reportHistoryList) {
				versionList.add(reportHistory.getVersion());
			}
		}
		return versionList;
	}
	
	/**
	 * 获取新的版本号
	 * @param applyId
	 * @param projectId
	 * @return
	 */
	public String getNewVersion(String lastVersion) {
		double num = Double.parseDouble(lastVersion.substring(1));
		num += 0.01;
		String nextVersion = "v" + (num % 1 == 0 ? String.format("%.1f",num) : String.format("%.2f",num));
		return nextVersion;
	}
	
	/**
	 * 修改是否导出
	 * @param projectId
	 * @param isExport
	 */
	@Transactional
	public ReportModel saveIsExport(ReportModel reportModel) {
		if(reportModel.getContentId() == null) { //新增
			reportDao.addReportContent(reportModel);
		} else { //修改
			ReportModel old = reportDao.queryReportContentByCon(reportModel);
			if(old == null) {
				throw new IllegalArgumentException("信息已过期，请刷新后重试");
			}
			reportDao.updateIsExport(reportModel);
		}
		ReportModel model = new ReportModel();
		model.setRelation(reportModel.getRelation());
		model.setProjectId(reportModel.getProjectId());
		return reportDao.queryReportContentByCon(model);
	}
	
	/**
	 * 根据ID查询项目信息
	 * @param projectId
	 * @return
	 */
	public ProjectModel queryProjectById(int projectId) {
		ProjectModel project = reportDao.queryProjectById(projectId);
		if(StringUtils.isNotBlank(project.getMethodId())) {
			String methodId = project.getMethodId();
			String[] methodIdArr = methodId.split(",");
			String method = "";
			for(String oneMethodId : methodIdArr) {
				method += "," + methodNameArr[Integer.parseInt(oneMethodId) - 1];
			}
			project.setMethod(method.substring(1));
		} else {
			project.setMethod("");
		}
		if(StringUtils.isNotBlank(project.getFinalMethod())) {
			project.setFinalMethodName(methodNameArr[Integer.parseInt(project.getFinalMethod()) - 1]);
		} else {
			project.setFinalMethodName("");
		}
		return project;
	}
	
	/**
	 * 生成报告word html
	 * @param projectId
	 * @return
	 */
	@Deprecated
	public StringBuilder generateReportHtml(ProjectModel project) {
		StringBuilder richHtml = new StringBuilder();
		//查询所有的标题
		String[] methodIdArr = null;
		List<Integer> typeList = new ArrayList<Integer>();
		typeList.add(Constants.AuthType_Report);
		if(StringUtils.isNotBlank(project.getMethodId())) {
			methodIdArr = project.getMethodId().split(",");
			for(String methodId : methodIdArr) {
				typeList.add(Integer.parseInt(Constants.AuthType_Report + "" + (Integer.parseInt(methodId) + 2)));
			}
		}
		List<Map<String, Object>> reportList = reportDao.queryAllReportContent(typeList);
		if(reportList != null && reportList.size() > 0) {
			List<Map<String, Object>> reportTree = EasyUITreeUtil.loopForTree(reportList,
					new ArrayList<Map<String, Object>>(), "id", "parentId", "sequence", "name",
					new String[] { "relation", "isExport", "serialNum", "titleLevel" });
			//递归生成word文档内容
			generateWordBody(reportTree, project.getProjectId(), richHtml);
		}
		return richHtml;
	}
	
	/**
	 * 递归生成word文档
	 * @param reportList
	 * @param projectId
	 * @param richHtml
	 */
	@Deprecated
	private void generateWordBody(List<Map<String, Object>> reportList, int projectId, StringBuilder richHtml) {
		for(Map<String, Object> reportModel : reportList) {
			//查询标题内容
			String relation = (String) reportModel.get("relation");
			if(StringUtils.isNotBlank(relation)) {
				ReportModel newReportModel = reportDao.queryReportContent((int) reportModel.get("id"),
						relation, projectId);
				//判断是否导出,设为否或者没设都不导出
				if((newReportModel.getIsExport() != null && newReportModel.getIsExport() == 1) 
						|| (newReportModel.getIsExportForProject() != null && newReportModel.getIsExportForProject() == 1)
						|| (newReportModel.getIsExport() == null && newReportModel.getIsExportForProject() == null 
							&& (StringUtils.isNotBlank(newReportModel.getContent()) || StringUtils.isNotBlank(newReportModel.getTemplate())))) {
					//导出
					//标题
					String titleHtml = "<p>";
					if(StringUtils.isNotBlank(newReportModel.getSerialNum())) {
						titleHtml += newReportModel.getSerialNum();
					}
					titleHtml += newReportModel.getAuthName();
					if(newReportModel.getTitleLevel() != null) {
						Integer titleLevel = newReportModel.getTitleLevel();
						if(titleLevel != null) {
							switch (titleLevel) {
								case 1:
									titleHtml = "<h1 style='text-align:center;font-family:SimHei;font-size:15pt;'>" + titleHtml + "</h1>";
									break;
								case 2:
									titleHtml = "<h2 style='font-family:SimHei;font-size:12pt;'>" + titleHtml + "</h2>";
									break;
								default:
									titleHtml = "<h" + titleLevel + ">" + titleHtml + "</h" + titleLevel + ">";
									break;
							}
						} 
					}
					titleHtml += "</p>";
					richHtml.append(titleHtml);
					//内容
					if(StringUtils.isNotBlank(newReportModel.getContent())) {
						richHtml.append(newReportModel.getContent());
					}
//					else if(StringUtils.isNotBlank(newReportModel.getTemplate())) {
//						richHtml.append(newReportModel.getTemplate());
//					}
				}
			}
			
			List<Map<String, Object>> child = (List<Map<String, Object>>) reportModel.get("children");
			if(child != null && child.size() > 0) {
				generateWordBody(child, projectId, richHtml);
			}
		}
	}
	
	/**
	 * 获取报告全部内容
	 * @param projectId 项目ID
	 * @param type 1：报告 2：说明
	 * @return
	 */
	public String queryAllReportContent(int projectId, int type) {
		StringBuilder content = new StringBuilder();
		ProjectModel project = this.queryProjectById(projectId);
		//查询所有的标题
		String[] methodIdArr = null;
		List<Integer> typeList = new ArrayList<Integer>();
		typeList.add(type);
		if(StringUtils.isNotBlank(project.getMethodId())) {
			methodIdArr = project.getMethodId().split(",");
			for(String methodId : methodIdArr) {
				typeList.add(Integer.parseInt(type + "" + (Integer.parseInt(methodId) + 2)));
			}
		}
		List<Map<String, Object>> reportList = reportDao.queryAllReportContent(typeList);
		if(reportList != null && reportList.size() > 0) {
			List<Map<String, Object>> reportTree = EasyUITreeUtil.loopForTree(reportList,
					new ArrayList<Map<String, Object>>(), "id", "parentId", "sequence", "name",
					new String[] { "relation", "isExport", "serialNum", "titleLevel" });
			generateContent(reportTree, projectId, content);
		}
		return content.toString();
	}
	
	/**
	 * 
	 * @param reportTree
	 * @param projectId
	 * @param content
	 */
	private void generateContent(List<Map<String, Object>> reportTree, int projectId, StringBuilder content) {
		for(int i = 0; i < reportTree.size(); i++) {
			Map<String, Object> reportModel = reportTree.get(i);
			//查询标题内容
			String relation = (String) reportModel.get("relation");
			if(StringUtils.isNotBlank(relation)) {
				ReportModel newReportModel = reportDao.queryReportContent((int) reportModel.get("id"),
						relation, projectId);
				if((newReportModel.getIsExport() != null && newReportModel.getIsExport() == 1) 
						|| (newReportModel.getIsExportForProject() != null && newReportModel.getIsExportForProject() == 1)) {
//				if(isExport != null && isExport == 1 && StringUtils.isNotBlank(relation)) {
//					content.append("<p style=\"text-indent:32px;line-height:150%\">-->>" + newReportModel.getAuthName() + "</p>");
//					content.append("<p style=\"text-indent:32px;line-height:150%\"><span style=\"font-size:16px;font-family:宋体\"><br/></span></p>");
					if(StringUtils.isNotBlank(newReportModel.getContent())) {
						content.append(newReportModel.getContent());
//						content.append("<p style=\"text-indent:32px;line-height:150%\"><span style=\"font-size:16px;font-family:宋体\"><br/></span></p>");
					}
				} else if(StringUtils.isNotBlank((String) reportModel.get("authName"))){
//					content.append("<p style=\"text-indent:32px;line-height:150%\">-->>" + reportModel.get("authName") + "</p>");
//					content.append("<p style=\"text-indent:32px;line-height:150%\"><span style=\"font-size:16px;font-family:宋体\"><br/></span></p>");
				}
			}
			List<Map<String, Object>> child = (List<Map<String, Object>>) reportModel.get("children");
			if(child != null && child.size() > 0) {
				generateContent(child, projectId, content);
			}
		}
	}
	
	/**
	 * 查找
	 * @param projectId
	 * @param type
	 * @param keyword
	 * @return
	 */
	public List<Map<String, Object>> findContent(int projectId, int type, String keyword) {
		List<Map<String, Object>> resultList = new ArrayList<Map<String,Object>>();
		ProjectModel project = this.queryProjectById(projectId);
		//查询所有的标题
		String[] methodIdArr = null;
		List<Integer> typeList = new ArrayList<Integer>();
		typeList.add(type);
		if(StringUtils.isNotBlank(project.getMethodId())) {
			methodIdArr = project.getMethodId().split(",");
			for(String methodId : methodIdArr) {
				typeList.add(Integer.parseInt(type + "" + (Integer.parseInt(methodId) + 2)));
			}
		}
		List<Map<String, Object>> reportList = reportDao.queryAllReportContent(typeList);
		if(reportList != null && reportList.size() > 0) {
			List<Map<String, Object>> reportTree = EasyUITreeUtil.loopForTree(reportList,
					new ArrayList<Map<String, Object>>(), "id", "parentId", "sequence", "name",
					new String[] { "relation", "isExport", "serialNum", "titleLevel", "fullName" });
			find(reportTree, projectId, keyword, resultList);
		}
		return resultList;
	}
	
	/**
	 * 
	 * @param reportTree
	 * @param projectId
	 * @param keyword
	 * @param resultList
	 */
	private void find(List<Map<String, Object>> reportTree, int projectId, String keyword, List<Map<String, Object>> resultList) {
		for(int i = 0; i < reportTree.size(); i++) {
			Map<String, Object> reportModel = reportTree.get(i);
			String relation = (String) reportModel.get("relation");
			if(StringUtils.isNotBlank(relation)) {
				ReportModel newReportModel = reportDao.queryReportContent((int) reportModel.get("id"),
						relation, projectId);
				if(StringUtils.isNotBlank(newReportModel.getContent())) {
					String content = newReportModel.getContent();
					content = removeHtmlTag(content);
					if(content.indexOf(keyword) != -1) {
						resultList.add(reportModel);
					}
				}
			}
			List<Map<String, Object>> child = (List<Map<String, Object>>) reportModel.get("children");
			if(child != null && child.size() > 0) {
				find(child, projectId, keyword, resultList);
			}
		}
	}
	
	 /**
     * 清除Html标签
     *
     * @param inputString 目标字符串
     * @return 处理后的结果
     */
    public static String removeHtmlTag(String inputString) {
        if (inputString == null)
            return null;
        String textStr = "";
        Pattern p_html;
        Matcher m_html;
        try {
            // 定义HTML标签的正则表达式
            String regEx_html = "<[^>]+>";

            p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
            m_html = p_html.matcher(inputString);
            textStr = m_html.replaceAll(""); // 过滤html标签
        } catch (Exception e) {
            e.printStackTrace();
        }
        return textStr;// 返回文本字符串
    }
	
	/**
	 * 生成报告word html
	 * @param projectId
	 * @return
	 * @throws Exception 
	 */
	public String generateReportHtmlByPoi(XWPFDocument doc, ProjectModel project, int type) throws Exception {
		String reportName = "";
		String headerName = "";
		switch (type) {
			case 1:
				reportName = "资产评估报告";
				headerName = "正文";
				break;
			case 2:
				reportName = "资产评估说明";
				headerName = "评估说明";
				break;
			default:
				break;
		}
		//设置纸张大小、页边距
		HtmlToWordUtil.setPageSize(doc, null);
		//添加自定义标题样式
		HtmlToWordUtil.addCustomHeadingStyle(doc, "标题 1", 0, "黑体", "30"); //黑体、小三
		HtmlToWordUtil.addCustomHeadingStyle(doc, "标题 2", 1, "黑体", "24"); //黑体、小四
		//生成页眉页脚
//		HtmlToWordUtil.createHeader(doc, null, project.getReportName() + reportName, headerName);
//		HtmlToWordUtil.createFooter(doc, null);
		//生成自动编号
		numIdArr.clear(); 
		numIdArr.add(HtmlToWordUtil.createNumStyle(doc, "%1、", STNumberFormat.CHINESE_COUNTING_THOUSAND));
		numIdArr.add(HtmlToWordUtil.createNumStyle(doc, "%1、", STNumberFormat.CHINESE_COUNTING_THOUSAND));
		//查询所有的标题
		String[] methodIdArr = null;
		List<Integer> typeList = new ArrayList<Integer>();
		typeList.add(type);
		if(StringUtils.isNotBlank(project.getMethodId())) {
			methodIdArr = project.getMethodId().split(",");
			for(String methodId : methodIdArr) {
				typeList.add(Integer.parseInt(type + "" + (Integer.parseInt(methodId) + 2)));
			}
		}
		List<Map<String, Object>> reportList = reportDao.queryAllReportContent(typeList);
		if(reportList != null && reportList.size() > 0) {
			List<Map<String, Object>> reportTree = EasyUITreeUtil.loopForTree(reportList,
					new ArrayList<Map<String, Object>>(), "id", "parentId", "sequence", "name",
					new String[] { "relation", "isExport", "serialNum", "titleLevel" });
			//递归生成word文档内容
			generateWordBodyByPoi(doc, reportTree, project, reportName, type, "", "");
		}
		StringBuilder warningMsgStr = new StringBuilder();
		for(int i = 0; i < warningMsgList.size(); i++) {
			String warningMsg = warningMsgList.get(i);
			if(i == 0) {
				warningMsgStr.append("<p>警告信息：</p>");
			}
			warningMsgStr.append("<p>" + warningMsg + "</p>");
		}
		for(int i = 0; i < errorMessageList.size(); i++) {
			String warningMsg = errorMessageList.get(i);
			if(i == 0) {
				warningMsgStr.append("<p>错误信息：</p>");
			}
			warningMsgStr.append("<p>" + warningMsg + "</p>");
		}
		warningMsgList = new ArrayList<String>();
		errorMessageList = new ArrayList<String>();
		return warningMsgStr.toString();
	}
	
	/**
	 * 使用poi递归生成word文档
	 * @param reportList
	 * @param projectId
	 * @param richHtml
	 * @throws Exception 
	 */
	private void generateWordBodyByPoi(XWPFDocument doc, List<Map<String, Object>> reportList,
			ProjectModel project, String reportName, int type, String header, String pageNum) throws Exception {
		int titleIndex = 1; //标题编号
		for(int i = 0; i < reportList.size(); i++) {
			Map<String, Object> reportModel = reportList.get(i);
			//查询标题内容
			String relation = (String) reportModel.get("relation");
			if(StringUtils.isNotBlank(relation)) {
				ReportModel newReportModel = reportDao.queryReportContent((int) reportModel.get("id"),
						relation, project.getProjectId());
				//判断是否导出,设为否或者没设都不导出
				if((newReportModel.getIsExport() != null && newReportModel.getIsExport() == 1) 
						|| (newReportModel.getIsExportForProject() != null && newReportModel.getIsExportForProject() == 1)
//						|| (newReportModel.getIsExport() == null && newReportModel.getIsExportForProject() == null 
//						&& StringUtils.isNotBlank(newReportModel.getContent()))
						) {
					//导出
					//标题
					String title = "";
					if(StringUtils.isNotBlank(newReportModel.getSerialNum())) {
						title += newReportModel.getSerialNum();
					}
					title += newReportModel.getAuthName();
					if(doc.getParagraphs().size() > 0 && newReportModel.getTitleLevel() != null && newReportModel.getTitleLevel() == 1) {
						//添加分节符
						if(doc.getLastParagraph() != null && !doc.getLastParagraph().isEmpty()) {
							XWPFParagraph newPara = doc.createParagraph();
							CTSectPr ctSectPr = HtmlToWordUtil.addNewSection(newPara);
							//添加页眉页脚
							if(StringUtils.isNotBlank(header)) {
								if(header.equals("说明")) { //页码是罗马数字
									HtmlToWordUtil.createHeader(doc, ctSectPr, "", "");
									HtmlToWordUtil.createFooterRoman(doc, ctSectPr);
								} else {
//									if(type == 2) {
//										header = "评估说明";
//									}
									if(reportName.equals("资产评估说明")) {
										HtmlToWordUtil.createHeader(doc, ctSectPr, project.getReportName() + reportName, "评估说明");
									} else {
										HtmlToWordUtil.createHeader(doc, ctSectPr, project.getReportName() + reportName, header);
									}
//									HtmlToWordUtil.createHeader(doc, ctSectPr, project.getProjectName() + reportName, header);
									HtmlToWordUtil.createFooter(doc, ctSectPr, false, pageNum);
								}
							} else {
								HtmlToWordUtil.createHeader(doc, ctSectPr, "", "");
								HtmlToWordUtil.createFooter(doc, ctSectPr, true, pageNum);
							}
							if(StringUtils.isNotBlank(newReportModel.getChName())) {
								header = newReportModel.getChName();
								pageNum = newReportModel.getPageNum();
							} else {
								header = "";
								pageNum = "";
							}
							if(i == reportList.size() - 1) { // 最后一个一级标题
								if(StringUtils.isNotBlank(header)) {
									if(reportName.equals("资产评估说明")) {
										HtmlToWordUtil.createHeader(doc, null, project.getReportName() + reportName, "评估说明");
									} else {
										HtmlToWordUtil.createHeader(doc, null, project.getReportName() + reportName, header);
									}
//									HtmlToWordUtil.createHeader(doc, null, project.getProjectName() + reportName, header);
									HtmlToWordUtil.createFooter(doc, null, false, pageNum);
								} else {
									HtmlToWordUtil.createHeader(doc, null, "", "");
									HtmlToWordUtil.createFooter(doc, null, true, pageNum);
								}
							}
						}
					}
					//添加分页符
					if(newReportModel.getAuthName().equals("委托人签章页") || newReportModel.getAuthName().equals("被评估单位签章页")) {
						XWPFParagraph para = doc.createParagraph();
//						para.setPageBreak(true);
						XWPFRun run = para.createRun();
						run.addBreak(BreakType.PAGE);
					}
					if(!notShowTitleList.contains(newReportModel.getAuthName())) {// && !newReportModel.getChName().equals("正文")
						XWPFParagraph para = doc.createParagraph();
						XWPFRun run = para.createRun();
						if(StringUtils.isNotBlank(newReportModel.getChName()) && newReportModel.getChName().equals("目录")) {//目录自动生成，最后生成
							para.setAlignment(ParagraphAlignment.CENTER); //居中
							HtmlToWordUtil.setParagraphTextStyleInfo(run, "黑体", "32");//黑体、三号
							run.setText("目    录");
							para = doc.createParagraph(); //空一行
							run = para.createRun();
							run.setText("");
							
							if(type == 1) {//评估报告
								para = doc.createParagraph();
								para.setAlignment(ParagraphAlignment.LEFT); //居左
								run = para.createRun();
								HtmlToWordUtil.setParagraphTextStyleInfo(run, "黑体", "32");//黑体、三号
								HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
					                    "360", STLineSpacingRule.Enum.forString("auto"));
								run.setText("第一册（声明、摘要、正文及附件）");
							}
							
							// get or create your paragraph
							para = doc.createParagraph();
							CTP ctP = para.getCTP();
							CTSimpleField toc = ctP.addNewFldSimple();
							toc.setInstr("TOC \\h");
							toc.setDirty(STOnOff.TRUE);
							HtmlToWordUtil.setTOCStyle(doc); //设置目录样式  字体、行间距
							continue;
						}
						para.setAlignment(ParagraphAlignment.LEFT);
						para.setVerticalAlignment(TextAlignment.CENTER);
						HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", false, "0", "0", true,  
			                    "360", STLineSpacingRule.Enum.forString("auto"));
						if(newReportModel.getTitleLevel() != null) {
							Integer titleLevel = newReportModel.getTitleLevel();
							if(titleLevel != null) {
								switch (titleLevel) {
									case 1:									
										if(newReportModel.getAuthName().equals("资产评估师承诺函")) { //处理目录不显示该项
											HtmlToWordUtil.setParagraphTextStyleInfo(run, "黑体", "30");//黑体、小三
										} else {
											para.setStyle("标题 1");
										}
										HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", true, "200", "200", true,  
							                    "240", STLineSpacingRule.Enum.forString("auto"));
										para.setAlignment(ParagraphAlignment.CENTER);
										break;
									case 2:
										para.setStyle("标题 2");
										para.setNumID(numIdArr.get(0));
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", true, "100", "100", true,  
							                    "288", STLineSpacingRule.Enum.forString("auto"));//1.2倍行距
										para.setAlignment(ParagraphAlignment.LEFT);
										break;
									case 3:
										title = NumberUtil.numberToChinese(titleIndex) + "、" + title;
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "宋体", "24");//宋体、小四
										para.setAlignment(ParagraphAlignment.LEFT);
										break;
									case 4:
										title = "(" + NumberUtil.numberToChinese(titleIndex) + ")" + title;
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "宋体", "24");
										break;
									case 5:
										title = titleIndex + "." + title;
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "宋体", "24");
										break;
									case 6:
										title = "（" + titleIndex + "）" + title;
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "宋体", "24");
										break;
									case 7:
										para.setNumID(numIdArr.get(1));
										HtmlToWordUtil.setParagraphFirstLine(para, 2);//首行缩进，2字符
										HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", true, "100", "100", true,  
							                    "288", STLineSpacingRule.Enum.forString("auto"));//1.2倍行距
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "黑体", "24");//黑体、小四
										break;
									default:
										HtmlToWordUtil.setParagraphTextStyleInfo(run, "宋体", "24");
										break;
								}
							}
						}
						run.setText(title);
					}
					if(StringUtils.isNotBlank(newReportModel.getChName()) && newReportModel.getChName().equals("说明")) {//企业关于进行资产评估有关事项的说明，特殊处理，分两节
						XWPFParagraph para = doc.createParagraph();
						XWPFRun run = para.createRun();
						para.setStyle("标题 1");
						para.setAlignment(ParagraphAlignment.CENTER);
						run.setText(title);

						//内容
						String content = newReportModel.getContent();
						if(StringUtils.isNotBlank(content)) {
							//处理应用规则
							String newContent = dealQuoteRule(project, newReportModel.getAuthId(), content, 2);
							//html转word
							HtmlToWordUtil htmlToWordUtil = new HtmlToWordUtil();
							try {
								htmlToWordUtil.htmlToWord(doc, newReportModel.getAuthName(), newContent);
							} catch (Exception e) {
								errorMessageList.add(newReportModel.getAuthName() + "：" + e.getMessage());
							}
							XWPFParagraph newPara = doc.createParagraph();
						}
						
						CTSectPr ctSectPr = HtmlToWordUtil.addNewSection(doc.getLastParagraph()); //分节符
						
						HtmlToWordUtil.createHeader(doc, ctSectPr, project.getReportName() + reportName, "评估说明");
//						HtmlToWordUtil.createHeader(doc, ctSectPr, project.getProjectName() + reportName, "说明");
						HtmlToWordUtil.createFooter(doc, ctSectPr, false, pageNum);
						para = doc.createParagraph();
						run = para.createRun();
						HtmlToWordUtil.setParagraphTextStyleInfo(run, "黑体", "30");
						HtmlToWordUtil.setParagraphSpacingInfo(para, true, "0", "0", true, "200", "200", true,  
			                    "240", STLineSpacingRule.Enum.forString("auto"));
						para.setAlignment(ParagraphAlignment.CENTER);
						run.setText(title);
					} else {
						//内容
						String content = newReportModel.getContent();
						if(StringUtils.isBlank(content) && (newReportModel.getAuthName().equals("封面") 
								|| newReportModel.getAuthName().equals("明细表封面"))) {
							int coverType = type;
							if(newReportModel.getAuthName().equals("明细表封面")) {
								coverType = 3;
							}
							content = createCover(project, coverType);
						}
						if(StringUtils.isNotBlank(content)) {
							if(newReportModel.getAuthName().equals("封面") 
								|| newReportModel.getAuthName().equals("明细表封面")) {//封面在一页上
								int line = (int) Math.ceil(Double.parseDouble(project.getReportName().length() + "") / 23) 
										+ (int) Math.ceil(Double.parseDouble(project.getEvaluateTarget().length() + "") / 23);
								if(line > 4) {
									Document coverDoc = Jsoup.parse(content, "utf-8");
									Elements eles = coverDoc.getElementsByTag("p");
									for(int k = 0; k < line - 4; k++) {
										eles.get(eles.size() - (k + 3)).remove();
									}
									content = coverDoc.getElementsByTag("body").get(0).html();
								}
							}
							//处理应用规则
							String newContent = dealQuoteRule(project, newReportModel.getAuthId(), content, 2);
							//html转word
							HtmlToWordUtil htmlToWordUtil = new HtmlToWordUtil();
							try {
								htmlToWordUtil.htmlToWord(doc, newReportModel.getAuthName(), newContent);
							} catch (Exception e) {
								errorMessageList.add(newReportModel.getAuthName() + "：" + e.getMessage());
							}
						}
					}	
					
//					else if(StringUtils.isNotBlank(newReportModel.getTemplate())) {//没有内容导出模板
//						HtmlToWordUtil.htmlToWord(doc, newReportModel.getAuthName(), newReportModel.getTemplate());
//					}
					titleIndex++;
				}
			}
			
			List<Map<String, Object>> child = (List<Map<String, Object>>) reportModel.get("children");
			if(child != null && child.size() > 0) {
				generateWordBodyByPoi(doc, child, project, reportName, type, header, pageNum);
			}
		}
	}
	
	/**
	 * 创建封面
	 * @param project
	 * @return
	 */
	private String createCover(ProjectModel project, int coverType) {
		String reportName = "";
		String partStr = "";
		String desc = "";
		switch(coverType) {
			case 1:
				reportName = "资产评估报告";
				partStr = "共一册　第一册";
				desc = "声明、摘要、正文及附件";
				break;
			case 2:
				reportName = "资产评估说明";
				partStr = "共x册　第x册";
				desc = "";
				break;
			case 3:
				reportName = "资产评估明细表";
				partStr = "共x册　第x册";
				desc = "××公司评估明细表";
				break;
		}
		String coverHtml = "<p style='line-height: 27px'>"
				+ "    <strong><span style='font-size:19px;font-family:宋体'>本报告依据中国资产评估准则编制</span></strong>"
				+ "</p>"
				+ "<p>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px;font-family:黑体;'>" + project.getReportName() + "</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px;font-family:黑体;'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:35px;font-family:黑体'>" + reportName + "</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:20px;font-family:仿宋'>" + project.getReportNo() + "</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:20px'>&nbsp;</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:21px;font-family:黑体'>" + partStr + "</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:21px;font-family:黑体'>" + desc + "</span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:24px'></span>"
				+ "</p>"
				+ "<p style='text-align:center;text-autospace:none'>"
				+ "    <span style='font-size:21px;font-family:黑体'>中通诚资产评估有限公司</span>"
				+ "</p>"
				+ "<p style='text-align: center;'>"
				+ "    <span style='font-size:21px;font-family:黑体;'>二○××年××月××日</span>"
				+ "</p>";
		return coverHtml;
	}
	
	/**
	 * 处理引用规则
	 * @param project
	 * @param authId
	 * @param htmlStr
	 * @return
	 * @throws Exception
	 */
	public String dealQuoteRule(ProjectModel project, int authId, String htmlStr, int quoteType) throws Exception {
		if(StringUtils.isBlank(htmlStr)) {
			return htmlStr;
		}
		//将html中的样式等过滤掉
//		htmlStr = StringUtil.stringFilter(htmlStr);
		
		StringBuilder str = new StringBuilder();
		//查询引用规则
		List<QuoteModel> quoteList = reportDao.queryQuoteList(authId);
		if(quoteList != null && quoteList.size() > 0) {
			
			//去掉table
			Document doc = Jsoup.parse(htmlStr);
			Elements tableEle = doc.getElementsByTag("table");
			if(tableEle != null && !tableEle.isEmpty()) {
				tableEle.remove();
			}
			String noTableHtmlStr = doc.outerHtml();
			//判断多个被替换的字符串 个数是否一致，不一致不替换
			//获取要替换的重复字符串的个数
			Map<String, Integer> keywordMap = new HashMap<String, Integer>();
			for(QuoteModel quote : quoteList) {
				if(quote.getType() == 3) {
					String keyword = quote.getKeyword();
					if(keywordMap.containsKey(keyword)) {
						keywordMap.put(keyword, keywordMap.get(keyword) + 1);
					} else {
						keywordMap.put(keyword, 1);
					}
				}
			}
			//判断文本中是否有相应个数的关键字，没有则不替换
			Iterator<String> it = keywordMap.keySet().iterator();
			while(it.hasNext()) {
				String keyword = it.next();
				int num = getSubCount(noTableHtmlStr, keyword);
//				noTableHtmlStr = noTableHtmlStr.replace(keyword, "");
				if(num >= keywordMap.get(keyword)) {
					keywordMap.put(keyword, 1); //替换
				} else {
					Map<String, Object> map = reportDao.queryAuthParentList(authId);
					warningMsgList.add(map.get("fullName") + "：关键字“" + keyword + "”规则有" + keywordMap.get(keyword) + "个，实际有" + num + "个，请检查。");
					
					keywordMap.put(keyword, 0); //不替换
//					throw new IllegalArgumentException(map.get("fullName") + "  中关键字“" + keyword + "”  规则有" + keywordMap.get(keyword) + "个，实际有" + num + "个,请检查。");
				}
			}
			
			for(QuoteModel quote : quoteList) {
				String beReplacedStr = ""; //被替换的字符串
				String newHtmlStr = ""; //替换的字符串
				int type = quote.getType();
				if(keywordMap.containsKey(quote.getKeyword()) && keywordMap.get(quote.getKeyword()) == 0) {//不替换
					continue;
				}
				if(type == 1) {//项目配置
					if(StringUtils.isNotBlank(quote.getRegex())) {//找到匹配正则表达式的字符串
						beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
					} else {
						beReplacedStr = quote.getKeyword();
					}
					Object field = getFieldValueByName(quote.getExpression(), project);
					if(quote.getExpression().equals("baseDate")) {
						Date baseDate = project.getBaseDate();
						if(baseDate != null) {
							newHtmlStr = sdf.format(baseDate);
							if(quoteType == 1) {
								newHtmlStr = "{" + newHtmlStr + "}";
							}
						} else if(quoteType == 2) {
							newHtmlStr = beReplacedStr.replace("{", "").replace("}", "");
						}
					} else if(quote.getExpression().equals("reportDate")){
						Date reportDate = project.getReportDate();
						if(reportDate != null) {
							newHtmlStr = sdf.format(reportDate);
						}
					} else if(quote.getExpression().equals("method")){
						String method = project.getMethod();
						if(method.indexOf(",") >= 0 && StringUtils.isNotBlank(project.getFinalMethod())) {
							method = method.replace(project.getFinalMethodName(), "");
							if(method.startsWith(",")) {
								method = project.getFinalMethodName() + method;
							} else {
								method = project.getFinalMethodName() + "," + method;
							}
							if(method.endsWith(",")) {
								method = method.substring(0, method.length() - 1);
							}
						}
						method = method.replace(",", "和");
						newHtmlStr = method;
					} else {
						if(field != null) {
							newHtmlStr = field + "";
						}
					}
				} else if(type == 2) {//评估报告日，大写
					Date reportDate = project.getReportDate();
					if(reportDate != null) {
						newHtmlStr = DateUtil.getUpperDate(reportDate);
					}
					if(StringUtils.isNotBlank(quote.getRegex())) {//找到匹配正则表达式的字符串
						beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
					} else {
						beReplacedStr = quote.getKeyword();
					}
				} else if(type == 3) {//引用明细表单元格值
					String relation = quote.getRelation();
					if(relation.indexOf(",") >= 0) {
						String[] relationArr = quote.getRelation().split(",");
						if(StringUtils.isNotBlank(project.getFinalMethod())) {
							relation = relationArr[Integer.parseInt(project.getFinalMethod()) - 1];
						} else if(StringUtils.isNotBlank(project.getMethodId())){
							relation = relationArr[Integer.parseInt(project.getMethodId().split(",")[0]) - 1];
						} else {
							continue;
						}
					}
					List<ExcelModel> excelModelList = reportDao.queryExcel(relation, project.getProjectId());
					if(excelModelList != null && excelModelList.size() > 0 && excelModelList.get(0) != null) {
						//查询表格内容
						ExcelModel excelModel = excelModelList.get(0);
						//查询表格模板
						List<ReportModel> reportModel = reportDao.queryTemplateByRelation(relation);
						String val = ExcelQuoteUtil.getExcelCell(excelModel.getContent(), reportModel.get(0).getTemplate(), 
								Integer.parseInt(quote.getRow()), Integer.parseInt(quote.getColumn()));
						if(StringUtils.isNotBlank(val)) {
							newHtmlStr = quote.getKeyword() + "为" + val + quote.getUnit();
							//获取被替换字符串
//							beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword());
							beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword(), quote.getUnit(), quoteType);
						} else if(quoteType == 2) {
							newHtmlStr = quote.getKeyword();
							beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword(), quote.getUnit(), quoteType);
						}
					} else if(quoteType == 2) {
						newHtmlStr = quote.getKeyword();
						beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword(), quote.getUnit(), quoteType);
					}
				} else if(type == 4) {//评估基准日起止日期
					Date baseDate = project.getBaseDate();
					if(baseDate != null) {
						String startDate = sdf.format(baseDate);
						Calendar cal = Calendar.getInstance();
						cal.setTime(baseDate);
						cal.add(Calendar.YEAR, 1);
						cal.add(Calendar.DAY_OF_YEAR, -1);
						String endDate = sdf.format(cal.getTime());
						newHtmlStr = "评估基准日" + startDate + "起，至" + endDate + "止";
						if(quoteType == 1) {
							newHtmlStr = "{" + newHtmlStr + "}";
						}
						//找到匹配正则表达式的字符串
						beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
					}
					if(quoteType == 2) {
						beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
						newHtmlStr = beReplacedStr.replace("{", "").replace("}", "");
					}
				} else if(type == 5) {//整表引用，去掉空值行
					String relation = quote.getRelation();
					if(StringUtils.isNotBlank(relation)) {//从单个明细表取值
						
						if(relation.indexOf(",") >= 0) {
							String[] relationArr = quote.getRelation().split(",");
							if(StringUtils.isNotBlank(project.getFinalMethod())) {
								relation = relationArr[Integer.parseInt(project.getFinalMethod()) - 1];
							} else if(StringUtils.isNotBlank(project.getMethodId())){
								relation = relationArr[Integer.parseInt(project.getMethodId().split(",")[0]) - 1];
							} else {
								continue;
							}
						}
						
						List<ExcelModel> excelModelList = reportDao.queryExcel(relation, project.getProjectId());
						if(excelModelList != null && excelModelList.size() > 0 && excelModelList.get(0) != null) {
							ExcelModel excelModel = excelModelList.get(0);
							if(StringUtils.isNotBlank(quote.getModel())) {//模板取值
								newHtmlStr = ExcelQuoteUtil.getExcelTable(excelModel.getContent(), quote.getModel(), relation);
							} else {//明细表转化
								//查询表格模板
								List<ReportModel> reportModel = reportDao.queryTemplateByRelation(relation);
								newHtmlStr = ExcelQuoteUtil.getExcelTable(excelModel.getContent(), reportModel.get(0).getTemplate(), quote, project);
							}
							if(StringUtils.isNotBlank(newHtmlStr)) {
								beReplacedStr = getBeReplacedTable(htmlStr, quote.getKeyword());
							}
						}
					} else {//从多个明细表取值
						newHtmlStr = getExcelTableFromMulti(quote.getModel(), project, quote.getUnit());
						beReplacedStr = getBeReplacedTable(htmlStr, quote.getKeyword());
					}
				} else if(type == 6) {
					String relation = quote.getRelation();
					if(relation.indexOf(",") >= 0) {
						String[] relationArr = quote.getRelation().split(",");
						if(StringUtils.isNotBlank(project.getFinalMethod())) {
							relation = relationArr[Integer.parseInt(project.getFinalMethod()) - 1];
						} else if(StringUtils.isNotBlank(project.getMethodId())){
							relation = relationArr[Integer.parseInt(project.getMethodId().split(",")[0]) - 1];
						} else {
							continue;
						}
					}
					List<ExcelModel> excelModelList = reportDao.queryExcel(relation, project.getProjectId());
					if(excelModelList != null && excelModelList.size() > 0 && excelModelList.get(0) != null) {
						//查询表格内容
						ExcelModel excelModel = excelModelList.get(0);
						//查询表格模板
						List<ReportModel> reportModel = reportDao.queryTemplateByRelation(relation);
						String val = ExcelQuoteUtil.getExcelCell(excelModel.getContent(), reportModel.get(0).getTemplate(), 
								Integer.parseInt(quote.getRow()), Integer.parseInt(quote.getColumn()));
						if(StringUtils.isNotBlank(val)) {
							val = val.replace(",", "");
							newHtmlStr = MoneyNumberUtil.numberToChinese((long) (Double.parseDouble(val) * 10000)) + "元整";
							//获取被替换字符串
//							beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword());
//							beReplacedStr = getBeReplacedStr(htmlStr, quote.getKeyword(), quote.getUnit(), quoteType);
							beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
						}
					}
				} else if(type == 7) { //六、	评估方法选择模块 特殊处理
					beReplacedStr = RegexUtils.regexFindMatcher(quote.getRegex(), htmlStr);
					if(quote.getKeyword().equals("××法和××法")) { //评估方法
						String method = project.getMethod();
						if(method.indexOf(",") >= 0 && StringUtils.isNotBlank(project.getFinalMethod())) {
							method = method.replace(project.getFinalMethodName(), "");
							if(method.startsWith(",")) {
								method = project.getFinalMethodName() + method;
							} else {
								method = project.getFinalMethodName() + "," + method;
							}
							if(method.endsWith(",")) {
								method = method.substring(0, method.length() - 1);
							}
						}
						method = method.replace(",", "和");
						newHtmlStr = "采用" + method + "进行评估";
					} else if(quote.getKeyword().equals("xx法")) { //最终评估方法
						Object field = getFieldValueByName(quote.getExpression(), project);
						if(field != null) {
							newHtmlStr = "采用" + field + "确定评估结论";
						}
					}
				} else {
					beReplacedStr = quote.getKeyword();
					newHtmlStr = quote.getKeyword();
				}
				if(StringUtils.isNotBlank(beReplacedStr) && StringUtils.isNotBlank(newHtmlStr)) {
					if(htmlStr.indexOf(beReplacedStr) != -1) {
						int index = htmlStr.indexOf(beReplacedStr) + beReplacedStr.length();
						str.append(htmlStr.substring(0, index).replace(beReplacedStr, newHtmlStr));
						htmlStr = htmlStr.substring(index);
					}
				}				
			}
		}
		if(StringUtils.isNotBlank(htmlStr)) {
			str.append(htmlStr);
		}
		return str.toString();
	}
	
	/**
	 * 获取字符串有某个字符串出现的次数
	 * @param str
	 * @param key
	 * @return
	 */
	public static int getSubCount(String str, String key) {
        int count = 0;
        int index = 0;
        while ((index = str.indexOf(key, index)) != -1) {
            index = index + key.length();

            count++;
        }
        return count;
    }
	
	/**
	 * 根据属性名获取属性值   
	 * @param fieldName
	 * @param o
	 * @return
	 * @throws Exception
	 */
	private Object getFieldValueByName(String fieldName, Object o) throws Exception {
		String firstLetter = fieldName.substring(0, 1).toUpperCase();
		String getter = "get" + firstLetter + fieldName.substring(1);
		Method method = o.getClass().getMethod(getter, new Class[] {});
		Object value = method.invoke(o, new Object[] {});
		return value;
	}
	
	/**
	 * 获取被替换的字符串
	 * @param str 整体字符串
	 * @param keyword 关键字
	 * @return
	 */
	private String getBeReplacedStr(String str, String keyword) {
		if(str.indexOf(keyword) < 0) {
			return keyword;
		}
		str = str.substring(str.indexOf(keyword));
		Integer lastIndex = null;
		for(String sign : breakSign) {
			int index = str.indexOf(sign);
			if(index != -1) {
				if(lastIndex == null) {
					lastIndex = index;
				} else if(lastIndex > index) {
					lastIndex = index;
				}
			}
		}
		if(lastIndex == null) {
			return keyword;
		}
		str = str.substring(0, lastIndex);
		return str;
	}
	
	/**
	 * 获取被替换的字符串
	 * @param str 整体字符串
	 * @param keyword 关键字
	 * @param unit 单位
	 * @return
	 */
	private String getBeReplacedStr_bak(String str, String keyword, String unit) {		
		if(str.indexOf(keyword) < 0) {
			return keyword;
		}
		str = str.substring(str.indexOf(keyword));
		
		Integer lastIndex = null;
		for(String sign : breakSign) {
			int index = str.indexOf(sign);
			if(index != -1) {
				if(lastIndex == null) {
					lastIndex = index;
				} else if(lastIndex > index) {
					lastIndex = index;
				}
			}
		}
		if(lastIndex != null) {
			str = str.substring(0, lastIndex);
		}
		
		if(StringUtils.isBlank(unit)){
			return str;
		} else if(str.indexOf(unit) < 0) {
			return keyword;
		}
		str = str.substring(0, str.indexOf(unit) + unit.length());
		return str;
	}
	
	/**
	 * 获取被替换的字符串
	 * @param str 整体字符串
	 * @param keyword 关键字
	 * @param unit 单位
	 * @return
	 */
	private String getBeReplacedStr(String str, String keyword, String unit, int type) {		
		if(str.indexOf(keyword) < 0) {
			return keyword;
		}
		if(str.indexOf("{" + keyword) < 0) {
			return getBeReplacedStr_bak(str, keyword, unit);
		}
		
		if(type == 1) {
			str = str.substring(str.indexOf("{" + keyword) + 1);
			
			Integer lastIndex = str.indexOf("}");
			if(lastIndex >= 0) {
				str = str.substring(0, lastIndex);
			}
		} else {
			str = str.substring(str.indexOf("{" + keyword));
			
			Integer lastIndex = str.indexOf("}");
			if(lastIndex >= 0) {
				str = str.substring(0, lastIndex + 1);
			}
		}
		
		return str;
	}
	
	/**
	 * 获取被替换的表格
	 * @param str
	 * @param keyword
	 * @return
	 */
	private String getBeReplacedTable(String str, String keyword) {
		if(str.indexOf(keyword) < 0) {
			return keyword;
		}
		str = str.substring(str.indexOf(keyword));
		if(str.indexOf("<table") >= 0 && str.indexOf("</table>") >= 0) {
			str = str.substring(str.indexOf("<table"), str.indexOf("</table>") + "</table>".length());
		} else {
			return keyword;
		}
		return str;
	}


	/**
	 * 从多个明细表中获取数据
	 * @param modelStr
	 * @param unit
	 * @return
	 * @throws Exception 
	 */
	private String getExcelTableFromMulti(String modelStr, ProjectModel project, String unit) throws Exception {
		Document modelDoc = Jsoup.parse(modelStr, "utf-8");
		Elements modelTable = modelDoc.getElementsByTag("table");
		Elements modelTrs = modelTable.get(0).getElementsByTag("tr");
		String method = project.getMethodId();//将不需要的评估方法去掉
		String[] methodArr = method.split(",");
		for(int i = 0; i < modelTrs.size(); i++) {
			Element modelTr = modelTrs.get(i);
			if(i >= 2 && i <= 4) {
				boolean flag = false;
				for(String methodId : methodArr) {
					if(i == (Integer.parseInt(methodId) + 1)) {
						flag = true;
						break;
					}
				}
				if(!flag) {
					modelTr.remove();
					continue;
				}
			}
			Elements modelTds = modelTr.getElementsByTag("td");
			for(Element modelTd : modelTds) {
				String text = modelTd.text().trim();
				if(text.startsWith("$") && text.endsWith("$")) { //引用
					String[] arr = text.substring(1, text.length() - 1).split(",");
					List<ExcelModel> excelModelList = reportDao.queryExcel(arr[0], project.getProjectId());
					if(excelModelList != null && excelModelList.size() > 0 && excelModelList.get(0) != null) {
						ExcelModel excelModel = excelModelList.get(0);
						//查询表格模板
						List<ReportModel> reportModel = reportDao.queryTemplateByRelation(arr[0]);
						String val = ExcelQuoteUtil.getExcelCell(excelModel.getContent(), reportModel.get(0).getTemplate(), 
								Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
						modelTd.text(val);
					} else {
						modelTd.text("");
					}
				} else if(text.startsWith("#") && text.endsWith("#")) { //计算
					Elements modelTrs2 = modelTable.get(0).getElementsByTag("tr");
					String expression = text.substring(1, text.length() - 1);
					List<String> epList = new ArrayList<String>();
					Pattern p = Pattern.compile("\\d+((\\.|\\,)\\d+)*|\\+|\\-|\\*|\\/|\\(|\\)|\\|");
			        Matcher m = p.matcher(expression);
			        while(m.find()){
			        	epList.add(m.group());
			        }
			        String s = "";
			        boolean isAbs = false;
			        for(int k = 0; k < epList.size(); k++) {
			        	String str = epList.get(k);
			        	if(str.contains(",")) {
			        		String[] strArr = str.split(",");
			        		String val = modelTrs2.get(Integer.parseInt(strArr[0]) - 1).getElementsByTag("td").get(Integer.parseInt(strArr[1]) - 1).text();
			        		if(StringUtils.isBlank(val) || !ValidateUtil.isNumber(val)) {//值为空，无法计算
			        			modelTd.text("");
			        			s = "";
			        			break;
			        		}
			        		s += "(" + val.replace(",", "") + ")";
			        	} else if(str.contains("|")) {
			        		if(!isAbs) {
				        		s += "Math.abs(";
				        		isAbs = true;
			        		} else {
			        			s+= ")";
			        			isAbs = false;
			        		}
			        	} else {
			        		s += str;
			        	}
			        }
			        if(StringUtils.isNotBlank(s)) {
				        ScriptEngineManager manager = new ScriptEngineManager();
				        ScriptEngine engine = manager.getEngineByName("js");
				        if (engine == null){
				        	throw new IllegalArgumentException("计算错误");
				        }
				        modelTd.text(nf.format(engine.eval(s)));
			        } else {
			        	modelTd.text("");
			        }
				}
			}
		}
		return modelTable.outerHtml();
	}
	
	/**
	 * 修改表格 增加一列
	 */
	public void alterTable() {
		List<Map<String, Object>> relationList = projectDao.queryZtcRelation();
		for(Map<String, Object> relation : relationList) {
			String tableId = relation.get("tableId") + "";
			projectDao.alterTable(tableId);
		}
	}
	
	/**
	 * 处理报告、说明内容，去掉html标签，获取纯文本
	 */
	public void dealData() {
		List<Map<String, Object>> relationList = projectDao.queryZtcRelation();
		for(Map<String, Object> relation : relationList) {
			String tableId = relation.get("tableId") + "";
			List<Map<String, Object>> dataList = projectDao.queryAllReportContent(tableId);
			if(dataList != null && dataList.size() > 0) {
				for(Map<String, Object> map : dataList) {
					String content = (String) map.get("content");
					if(StringUtils.isNotBlank(content)) {
						String newContent = this.removeAllHtmlTag(content);
						projectDao.updateReportContent(tableId, Integer.parseInt(map.get("contentId") + ""), newContent);
					}
				}
			}
		}
	}
	
	 /**
     * 清除Html标签
     *
     * @param inputString 目标字符串
     * @return 处理后的结果
     */
    public String removeAllHtmlTag(String inputString) {
        if (StringUtils.isBlank(inputString))
            return null;
        String htmlStr = inputString; // 含html标签的字符串
        String textStr = "";
        Pattern p_script;
        Matcher m_script;
        Pattern p_style;
        Matcher m_style;
        Pattern p_html;
        Matcher m_html;
        Pattern p_special;
        Matcher m_special;
        try {
            //定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
            String regEx_script = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>";
            //定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
            String regEx_style = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
            // 定义HTML标签的正则表达式
            String regEx_html = "<[^>]+>";
            // 定义一些特殊字符的正则表达式 如：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            String regEx_special = "\\&[a-zA-Z]{1,10};";

            p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE);
            m_script = p_script.matcher(htmlStr);
            htmlStr = m_script.replaceAll(""); // 过滤script标签
            p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE);
            m_style = p_style.matcher(htmlStr);
            htmlStr = m_style.replaceAll(""); // 过滤style标签
            p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE);
            m_html = p_html.matcher(htmlStr);
            htmlStr = m_html.replaceAll(""); // 过滤html标签
            p_special = Pattern.compile(regEx_special, Pattern.CASE_INSENSITIVE);
            m_special = p_special.matcher(htmlStr);
            htmlStr = m_special.replaceAll(""); // 过滤特殊标签
            textStr = htmlStr;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return textStr;// 返回文本字符串
    }
}